package manager

import ext.log
import org.eclipse.paho.client.mqttv3.*
import org.json.JSONObject
import task.MatchResetTask
import task.RefreshSellTask
import task.RefreshWaresTask
import web.WebAppRequestHandler
import java.nio.charset.Charset

object MQTTManager : MqttCallback, Runnable {

    private const val ID_PUSH_PRICE = "pushprice"
    private const val ID_TEMPER_SET = "setTemperature" // 温度报警
    private const val ID_TEMPER_CONTROL = "controlTemperature" //温度控制
    private const val ID_STATUS = "status" // 再售, 停售
    private const val ID_RESTART = "restart"
    private const val ID_MCU_UPDATE = "updateclientAndlower" // 客户端 单片机升级
    private const val ID_ADV = "setAdvertise"
    private const val ID_MATCH_RESET = "match.reset"

   // private const val Host = "tcp://106.12.198.37:1883" // 百度云
   // private const val Host = "tcp://106.15.126.180:1883" // 阿里云
    private const val Host = "tcp://news.hontech-rdcenter.com:1883"
    private const val UserName = "xdh"
    private const val Password = "xdh123"

    private const val TOPIC_MCU_OTA = "topic/log"

    var client = MqttClient(Host, AppManager.MacAddress, null)

    fun connectToServer() {
        AsyncTask.post(this)
    }

    fun sendLog(msg: String) {
        try {
            client.publish(TOPIC_MCU_OTA, ("设备:${AppManager.MacAddress} " +
                    "${AppManager.MachCode} " +
                    "$msg").toByteArray(Charsets.UTF_8), 2, false)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun publish(topic: String, body: String) {

        AsyncTask.post {
            try {
                client.publish(topic, body.toByteArray(Charsets.UTF_8), 0, false)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    override fun run() {
        try {
            log("开始连接MQTT", "MQTT连接")
            connect()
        } catch (e: Exception) {
            e.printStackTrace()
            AsyncTask.postDelayed(this, 15000)
        }
    }

    private fun connect() {
        if (client.isConnected) {
            log("MQTT已经连接", "MQTT连接")
            return
        }

        val options = MqttConnectOptions()
        options.userName = UserName
        options.password = Password.toCharArray()
        options.keepAliveInterval = 20
        options.connectionTimeout = 5
        options.isCleanSession = true
        options.mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1
        log("MQTT开始连接之前", "MQTT连接")

        client.setCallback(this)

        client.connect(options)
        client.subscribe(AppManager.MacAddressTopic, 2)
        client.subscribe(AppManager.WebAppReqTopic, 0)
        log("MQTT连接成功", "MQTT连接")
    }

    override fun messageArrived(topic: String, message: MqttMessage) {

        try {
            if (topic == AppManager.MacAddressTopic) {
                val messageStr = String(message.payload, Charset.forName("utf-8"))
                log("MQTT消息:$topic--------$messageStr")
                onReceive(messageStr)
                return
            }

            if (topic == AppManager.WebAppReqTopic) {
                WebAppRequestHandler.onRequest(String(message.payload, Charsets.UTF_8))
            }

        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun connectionLost(cause: Throwable) {
        log("MQTT连接断开", "MQTT连接断开")
        cause.printStackTrace()
        AsyncTask.postDelayed(this, 15000)
    }

    override fun deliveryComplete(token: IMqttDeliveryToken) {
        log("MQTT消息发送成功", "MQTT发送")
    }

    private fun onReceive(msg: String) {

        val json = JSONObject(msg)
        val id = json.getString("id")

        when (id) {

            ID_MATCH_RESET -> {
                AsyncTask.post(MatchResetTask())
            }

            ID_PUSH_PRICE -> {
                log("重新加载商品属性消息")
                AsyncTask.post(RefreshWaresTask())
            }

            ID_TEMPER_SET -> {
                TempValueManager.refreshAsync()
            }

            ID_TEMPER_CONTROL -> {
                HeatManager.refreshAsync()
            }

            ID_RESTART -> AppManager.resetSystem()

            ID_STATUS -> {
                AsyncTask.post(RefreshSellTask())
            }

            ID_MCU_UPDATE -> {
                val param = json.getJSONObject("param")
                VersionManager.updateWithServer(param)
            }

            ID_ADV -> {
                AdvertisingManager.refreshWithAsync()
            }

        }

    }

}